package com.x52im.rainbowchat.http.logic.logic;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.eva.epc.common.util.CommonUtils;
import com.eva.epc.common.util.RestHashMap;
import com.eva.framework.Processor;
import com.eva.framework.dbpool.DBDepend;
import com.eva.framework.dbpool.DBShell;
import com.eva.framework.utils.EndsExceptionFactory;
import com.x52im.rainbowchat.cache.UsersInfoCacheProvider;
import com.x52im.rainbowchat.cache.dto.UserInfo4Cache;
import com.x52im.rainbowchat.http.dao.MoneyDAO;
import com.x52im.rainbowchat.http.dao.UserDAO;
import com.x52im.rainbowchat.http.logic.AbstractJobDispatcher;
import com.x52im.rainbowchat.http.logic.LogicProcessor2;
import com.x52im.rainbowchat.http.logic.LogicUtils;
import com.x52im.rainbowchat.http.logic.dto.UserRegisterDTO;
import com.x52im.rainbowchat.http.util.JedisTools;
import com.x52im.rainbowchat.http.util.ip.IPSeeker;
import com.x52im.rainbowchat.http.util.ip._Utils;

import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

public class RegisterJobDispatcher extends AbstractJobDispatcher {
    DBShell db = LogicProcessor2.db;

    /**
     * 维护注册管理.
     *
     * @param action_id 维护类型，SysConstant中的操作类型常量
     * @param newData   客端发送过来的本次修改新数据(可能为空，理论上与oldData不会同时空）
     * @param oldData   客端发送过来的本次修改前的老数据(可能为空，理论上与newData不会同时空）
     * @param userName  操作者的用户名
     * @return 返回给客户端的对象
     */
    @Override
    public String dispatch(int action_id, Object newData, Object oldData, Processor.User user) throws Exception {
        Vector sqls = new Vector(2);
        Vector values = new Vector(2);

        switch (action_id) {
            // 【接口1008-1-7】完成注册过程
            // 》当前正在被使用于：APP端、Web端
            case ACTION_APPEND1: {
                return ACTION_APPEND1(action_id, newData, oldData, user);
            }

            // 【接口1008-1-8】修改个人信息，包括昵称、性别
            // 》当前正在被使用于：APP端
            case ACTION_APPEND2: {
                return ACTION_APPEND2(action_id, newData, oldData, user);
            }
            // 【接口1008-1-9】修改登陆密码
            // 》当前正在被使用于：APP端、Web端
            case ACTION_APPEND3: {
                return ACTION_APPEND3(action_id, newData, oldData, user);
            }
            // 【接口1008-1-22】更新个性签名（what's up）
            // 》当前正在被使用于：APP端
            case ACTION_APPEND4: {
                return ACTION_APPEND4(action_id, newData, oldData, user);
            }
            // 【接口1008-1-24】更新个人其它说明
            // 》当前正在被使用于：APP端
            case ACTION_APPEND6: {
                return ACTION_APPEND6(action_id, newData, oldData, user);
            }
            // 【接口1008-1-25】更新个人信息中的昵称、性别、个性签名、其它说明的综合接口
            // 》当前正在被使用于：Web端（当对接RainbowChat-Web产品时）
            // 》说明：本综合接口目前主要是用于Web版中的修改个人信息的功能。当然，并不限制它的使用场景，请按需使用。
            case ACTION_APPEND7: {
                return ACTION_APPEND7(action_id, newData, oldData, user);
            }

            // 发送验证码短信
            case ACTION_APPEND8: {
                return ACTION_APPEND8(action_id, newData, oldData, user);
            }

            default:
                throw EndsExceptionFactory.INVALID_ACTION_ID(action_id);
        }
    }

    private String ACTION_APPEND8(int action_id, Object newData, Object oldData, Processor.User user) throws Exception {
        System.out.println(Thread.currentThread().getName());
        JSONObject nwObj = JSONObject.parseObject((String) newData);
        String phone = nwObj.getString("phone");
        String type = nwObj.getString("type");  // 1注册 2找回密码 3设置支付密码
        if (!LogicUtils.isMobile(phone)) {
            return "0";
        }
        String randomCode = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
        SendSmsResponse sendSmsResponse = LogicUtils.sendSMSVerificationCode(phone, randomCode);
        String code = sendSmsResponse.getBody().getCode();
        String message = sendSmsResponse.getBody().getMessage();

        Map map = new HashMap();
        map.put("code", code);
        map.put("message", message);
        map.put("randomCode", randomCode);

        String key = null;
        if (type.equals("1")) {
            key = JedisTools.getSmsRegisterUserKey(phone);
        } else if (type.equals("2")) {
            key = JedisTools.getSmsFindpswUserKey(phone);
        } else if (type.equals("3")) {
            key = JedisTools.getSmsPaypswKey(phone);
        }

        JedisTools.set(key, randomCode, 300);

//        String smsValue = JedisTools.get(key);
//        if (CommonUtils.isStringEmpty(smsValue)) {
//            // 如果缓存里没有验证码则发送验证码
//            LogicUtils.sendSMSVerificationCode(phone, randomCode);
//            JedisTools.set(key, randomCode, 300);   // 都是5分钟后失效
//        } else {
//            // 如果缓存里有验证码则取缓存里的验证码并且延迟2分钟失效
//            map.put("randomCode", smsValue);
//            JedisTools.set(key, smsValue, 120);
//        }

//        String key = "_" + phone;
//        if (code.equalsIgnoreCase("OK")) {
//            UserInfo4Cache regUserInfo = UsersInfoCacheProvider.getInstance().get(key);
//            if (regUserInfo == null) {
//                UserInfo4Cache info4Cache = UserInfo4Cache.create(phone, randomCode);
//                UsersInfoCacheProvider.getInstance().getAndSet(key, info4Cache);
//            }
//        }
        return JSON.toJSONString(map);
    }

    private String ACTION_APPEND7(int action_id, Object newData, Object oldData, Processor.User user) throws Exception {
        Vector sqls = new Vector(2);
        Vector values = new Vector(2);

        JSONObject nwObj = JSONObject.parseObject((String) newData);

        sqls.add("UPDATE missu_users SET nickname=?,user_sex=?,what_s_up=?,user_desc=? WHERE user_uid=?");
        values.add(new Object[]{
                nwObj.getString("nickName")
                , nwObj.getString("sex")
                , nwObj.getString("whats_up")
                , nwObj.getString("user_desc")
                , nwObj.getString("uid")});
        boolean res = db.update(sqls, values, true);

        //** 【高速缓存】即时更新用户缓存数据（因为更新了用户的昵称）
        UsersInfoCacheProvider.getInstance().reloadOneFromDB(nwObj.getString("uid"));

        return res ? "1" : "0";// 1 表示更新成功，否则失败
    }

    private String ACTION_APPEND6(int action_id, Object newData, Object oldData, Processor.User user) throws Exception {
        Vector sqls = new Vector(2);
        Vector values = new Vector(2);

        JSONObject nwObj = JSONObject.parseObject((String) newData);
        sqls.add("UPDATE missu_users SET user_desc=? WHERE user_uid=?");
        values.add(new Object[]{nwObj.getString("user_desc"), nwObj.getString("uid")});
        boolean res = db.update(sqls, values, true);
        return res ? "1" : "0";// 1 表示更新成功，否则失败
    }

    private String ACTION_APPEND4(int action_id, Object newData, Object oldData, Processor.User user) throws Exception {
        Vector sqls = new Vector(2);
        Vector values = new Vector(2);

        JSONObject nwObj = JSONObject.parseObject((String) newData);
        sqls.add("UPDATE missu_users SET what_s_up=? WHERE user_uid=?");
        values.add(new Object[]{nwObj.getString("whats_up"), nwObj.getString("uid")});
        boolean res = db.update(sqls, values, true);
        return res ? "1" : "0";// 1 表示更新成功，否则失败
    }

    private String ACTION_APPEND3(int action_id, Object newData, Object oldData, Processor.User user) throws Exception {
        Vector sqls = new Vector(2);
        Vector values = new Vector(2);

        JSONObject nwObj = JSONObject.parseObject((String) newData);

        // 返回值：1 表示更新成功，0 表示失败，2 表示原密码不正确
        String ret = "0";

        String sql = "SELECT user_psw FROM missu_users WHERE user_uid = '"
                + nwObj.getString("uid")
                + "'";
        String oldPsw = db.querySingleItem(sql);
        if (!CommonUtils.isStringEmpty(oldPsw)) {
            if (oldPsw.equals(CommonUtils.encyptPassword(nwObj.getString("old_psw"), ""))) {
                sqls.add("UPDATE missu_users SET user_psw=? WHERE user_uid=? AND user_psw=?");
                values.add(new Object[]{
                        CommonUtils.encyptPassword(nwObj.getString("psw"), "")
                        , nwObj.getString("uid")
                        , CommonUtils.encyptPassword(nwObj.getString("old_psw"), "")
                });
                boolean res = db.update(sqls, values, true);
                ret = res ? "1" : "0";
            } else {
                ret = "2";
            }
        }
        return ret;
    }

    private String ACTION_APPEND2(int action_id, Object newData, Object oldData, Processor.User user) throws Exception {
        Vector sqls = new Vector();
        Vector values = new Vector();

        JSONObject nwObj = JSONObject.parseObject((String) newData);

        sqls.add("UPDATE missu_users SET nickname=?,user_sex=? WHERE user_uid=?");
        values.add(new Object[]{nwObj.getString("nickName"), nwObj.getString("sex"), nwObj.getString("uid")});
        boolean res = db.update(sqls, values, true);

        //** 【高速缓存】即时更新用户缓存数据（因为更新了用户的昵称）
        UsersInfoCacheProvider.getInstance().reloadOneFromDB(nwObj.getString("uid"));

        return res ? "1" : "0";// 1 表示更新成功，否则失败
    }

    private String ACTION_APPEND1(int action_id, Object newData, Object oldData, Processor.User user) throws Exception {
        UserRegisterDTO urd = JSON.parseObject((String) newData, UserRegisterDTO.class);
        if (!CommonUtils.isStringEmpty(urd.getUser_phone(), true) && !CommonUtils.isStringEmpty(urd.getSms_code(), true)) {
            return _regByPhone(user, urd);
        } else if (!CommonUtils.isStringEmpty(urd.getUser_mail(), true)) {
            return _regByEmail(user, urd);
        }
        // 生成账户信息
        return null;
    }

    /**
     * 通过电话和验证码注册
     */
    private String _regByPhone(Processor.User user, UserRegisterDTO urd) throws Exception {
        UserDAO userDAO = new UserDAO();
        String existPhone = userDAO.queryUserByPhone(urd.getUser_phone());
        String newUidForReturn = null;
        String message = null;
        if (CommonUtils.isStringEmpty(existPhone)) {
            // 如果电话不存在则将查找缓存
            String key = JedisTools.getSmsRegisterUserKey(urd.getUser_phone());
            String smsCode = JedisTools.get(key);
            if (CommonUtils.isStringEmpty(smsCode)) {
                message = "请重新获取验证码";
            } else {
                if (!smsCode.equals(urd.getSms_code())) {
                    message = "验证码输入错误";
                } else {
                    userDAO.insertUser(urd, user.getIp());
                    newUidForReturn = userDAO.queryUserByPhone(urd.getUser_phone());
                    MoneyDAO moneyDAO = new MoneyDAO();
                    moneyDAO.insertAccount(newUidForReturn);
                    UsersInfoCacheProvider.getInstance().reloadOneFromDB(newUidForReturn);
                    if (newUidForReturn != null) {
                        JedisTools.delkeyObject(key);
                        message = "注册成功";
                    } else {
                        message = "注册失败请联系管理员";
                    }
                }
            }
        } else {
            message = "该号码已经存在";
        }
        Map map = new HashMap();
        map.put("new_uid", newUidForReturn);
        map.put("message", newUidForReturn);
        return JSON.toJSONString(map);
    }

    /**
     * 通过邮箱注册
     */
    private String _regByEmail(Processor.User user, UserRegisterDTO urd) throws Exception {
        UserDAO userDAO = new UserDAO();
        String newUidForReturn = null;
        String existMail = userDAO.queryUserByEmail(urd.getUser_mail());
        if (CommonUtils.isStringEmpty(existMail)) {
            userDAO.insertUser(urd, user.getIp());
            newUidForReturn = userDAO.queryUserByEmail(urd.getUser_mail());
            UsersInfoCacheProvider.getInstance().reloadOneFromDB(newUidForReturn);
        } else {
            newUidForReturn = "0";
        }
        return JSON.toJSONString(RestHashMap.n().p("new_uid", newUidForReturn));
    }
}
